package main

import (
	"fmt"
	_ "github.com/boltdb/bolt"
	_ "github.com/go-sql-driver/mysql"
	"go-test/src/test"
	"time"
)

// 程序执行的入口。如果有 init() 函数则会先执行 init() 函数
func main() {

	// 内部方法调用
	//testInnerMethodInvoke()

	// 并发调用
	//runtime.GOMAXPROCS(runtime.NumCPU())

	// 1、并发的使用
	concurrent1()

	// 2、使用通道在不同的线程间传递数据
	// 创建通道
	totalChan := make(chan int, 1)
	// 创建 sum1 线程
	go sum1(totalChan, 3)
	// main主线程从通道中取
	total := <-totalChan
	fmt.Println(total)
}

func concurrent1() {
	for i := 0; i <= 10; i++ {
		go fmt.Println(i)
	}
}

func sum1(totalChan chan int, max int) {
	var sum int
	for i := 0; i <= max; i++ {
		sum += i
	}

	//time.Sleep(time.Millisecond*3000)

	// 放入通道
	totalChan <- sum
}

//func init(){
//	fmt.Println("=====go-test init=====")
//}

func testInnerMethodInvoke() {
	fmt.Println("InnerMethodInvoke")

	// 1、方法调用
	// 外部包方法调用
	test.OuterMethodInvoke()

	// 2、变量
	var welcomeMsg string = "hello go"
	fmt.Println(welcomeMsg)

	var a, b int = 1, 2
	//var a,b int
	//a,b = 1,2
	fmt.Println(a, b)

	var d = true
	fmt.Println(d)

	simpleValue := 12.3
	fmt.Println(simpleValue)

	// 3、值类型。"="在内存中将 i 的值进行了拷贝
	aa := 66
	bb := aa
	aa = 88
	fmt.Println(aa, bb)
	// 变量的内存地址
	fmt.Println(&aa, &bb)

	rawArr := [...]int{1, 2, 3}
	targetarr := rawArr
	rawArr[0] = 0
	fmt.Println(rawArr, targetarr)

	// 指针
	var ptr *int
	fmt.Printf("ptr 的值为 : %x\n", ptr)
	if ptr == nil {
		fmt.Println("ptr is nil")
	}

	// 结构体
	jack := test.UserInfo{1, "jack", 20}
	//jack :=test.UserInfo{Id: 1, Name: "jack", Age: 20}
	fmt.Println(jack)

	jack.Age = 21
	fmt.Println(jack)

	// 切片
	//var arr []int
	slice := make([]int, 1)
	//arr :=make([]int,10)
	slice[0] = 1
	slice = append(slice, 2) // 追加元素
	slice = append(slice, 3)
	fmt.Println(slice)
	fmt.Println(len(slice), cap(slice))
	fmt.Println(slice[0:1])
	fmt.Println(slice[1:2])

	arr2 := slice
	arr3 := slice[:]
	fmt.Println(arr2, arr3)

	var emptySlice []int
	if emptySlice == nil {
		fmt.Println(len(emptySlice))
	}

	// 数据无法拷贝到容量为0的切片中
	copy(emptySlice, slice)
	fmt.Println(emptySlice)

	sourceSlice := slice
	targetSlice := make([]int, len(slice))
	copy(targetSlice, sourceSlice)
	fmt.Println(targetSlice)

	// 遍历
	for i, value := range targetSlice {
		fmt.Println(i, value)
	}

	fmt.Println("===============")
	for i := 0; i < len(targetSlice); i++ {
		fmt.Println(i, targetSlice[i])
	}

	var userInfoSlice []test.UserInfo
	mark1 := test.UserInfo{Id: 1, Name: "mark1", Age: 1}
	mark2 := test.UserInfo{Id: 2, Name: "mark2", Age: 2}
	userInfoSlice = append(userInfoSlice, mark1)
	userInfoSlice = append(userInfoSlice, mark2)
	for _, userInfo := range userInfoSlice {
		fmt.Println(userInfo)
	}

	// map
	provinceMap := make(map[string]string)
	provinceMap["湖南"] = "长沙"
	provinceMap["湖北"] = "武汉"
	provinceMap["江西"] = "南昌"

	delete(provinceMap, "江西")
	for key, value := range provinceMap {
		fmt.Println(key, value)
	}

	changeValue := 10
	afterChangeValue := float32(changeValue)
	fmt.Println(afterChangeValue)

	a12 := 1.84
	b12 := int(a12)
	fmt.Println(b12)

	// 接口，并发
	iphone := new(test.Iphone)
	go iphone.Call()
	fmt.Println("after call")

	time.Sleep(1000 * time.Millisecond)

	// 通道
	ch := make(chan int, 2)
	ch <- 1
	ch2 := <-ch
	fmt.Println(ch2)

	s := []int{7, 2, 8, -9, 4, 0}

	c := make(chan int)
	go sum(s[:len(s)/2], c)
	go sum(s[len(s)/2:], c)
	x, y := <-c, <-c // 从通道 c 中接收

	fmt.Println(x, y, x+y)

}

func sum(s []int, c chan int) {
	sum := 0
	for _, v := range s {
		sum += v
	}
	c <- sum // 把 sum 发送到通道 c
}
